<?php
namespace app\api\controller;
use app\common\controller\Api;
use Exception;
use think\Db;

/**
 * 微信回调
 */
class Notifyx extends Api
{
    protected $noNeedLogin = ['*'];

    public function _initialize()
    {
        parent::_initialize();
    }

    /**
     * 充值成功
     */
    public function notifyxRecharge()
    {
        \think\Log::write('notifyx-comein:');

        $paytype = $this->request->param('paytype');
        $pay =  \addons\epay\library\Service::checkNotify($paytype);
        if (!$pay) {
            return json(['code' => 'FAIL', 'message' => '失败'], 500, ['Content-Type' => 'application/json']);
        }

        // 获取回调数据，V3和V2的回调接收不同
        $data =  \addons\epay\library\Service::isVersionV3() ? $pay->callback() : $pay->verify();
        // $data = $this->request->param();
        try {
            //微信支付V3返回和V2不同
            if ( \addons\epay\library\Service::isVersionV3() && $paytype === 'wechat') {
                $data = $data['resource']['ciphertext'];
                $data['total_fee'] = $data['amount']['total'];
            }

            \think\Log::record($data);
            //获取支付金额、订单号
            $payamount = $paytype == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100;
            $out_trade_no = $data['out_trade_no'];

            \think\Log::record("回调成功，订单号：{$out_trade_no}，金额：{$payamount}");
            $model = new \app\api\model\matketing\RechargePackageOrder();
            $model = $model::get(['order_sn' => $out_trade_no]);
            if ($model->status == 1) {
                \think\Log::record("订单已支付,重复请求：{$out_trade_no}");
                throw new \Exception("订单已支付,重复请求：{$out_trade_no}");
            }
            if (!$model) {
                \think\Log::record("订单不存在：{$out_trade_no}");
                throw new \Exception("订单不存在：{$out_trade_no}");
            }

            $model->status = 1;
            $result = $model->save();

            if (!$result) {
                \think\Log::record("订单更新失败：{$out_trade_no}");
                throw new \Exception("订单更新失败：{$out_trade_no}");
            }

            $user = new \app\api\model\User();
            $user = $user::get($model->user_id);
            $user->setUpdateMoneyParams(["memo"=>"含充值{$model->money},赠送{$model->gift_money}","gift_money"=>$model->gift_money,'title'=>'充值金额','datatype'=>10]);
            $user->setInc('money', $model->money + $model->gift_money);

            //你可以在此编写订单逻辑
        } catch (Exception $e) {
            \think\Log::record("回调逻辑处理错误:" . $e->getMessage(), "error");
            return json(['code' => 'FAIL', 'message' => '失败'], 500, ['Content-Type' => 'application/json']);
        }

        //下面这句必须要执行,且在此之前不能有任何输出
        if ( \addons\epay\library\Service::isVersionV3()) {
            return $pay->success()->getBody()->getContents();
        } else {
            return $pay->success()->send();
        }
        // return json(['code' => 'SUCCESS', 'message' => '成功']);
    }


    /**
     * 订单支付成功
     */
    public function notifyxOrder()
    {
        \think\Log::write('notifyx-order:');
        $paytype = $this->request->param('paytype');
        $pay =  \addons\epay\library\Service::checkNotify($paytype);
        if (!$pay) {
            return json(['code' => 'FAIL', 'message' => '失败'], 500, ['Content-Type' => 'application/json']);
        }

        // 获取回调数据，V3和V2的回调接收不同
        $data =  \addons\epay\library\Service::isVersionV3() ? $pay->callback() : $pay->verify();
        // $data = $this->request->param();
        try {
            //微信支付V3返回和V2不同
            if ( \addons\epay\library\Service::isVersionV3() && $paytype === 'wechat') {
                $data = $data['resource']['ciphertext'];
                $data['total_fee'] = $data['amount']['total'];
            }

            \think\Log::record($data);
            //获取支付金额、订单号
            $payamount = $paytype == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100;
            $out_trade_no = $data['out_trade_no'];
            \think\Log::record("回调成功，订单号：{$out_trade_no}，金额：{$payamount}");
            $model = new \app\api\model\order\OrderMaster();
            $model = $model::get(['out_trade_no' => $out_trade_no]);
            if (!$model) {
                \think\Log::record("订单不存在：{$out_trade_no}");
                throw new \Exception("订单不存在：{$out_trade_no}");
            }
            if($model->pay_status == 1){
                \think\Log::record("订单已支付,重复请求：{$out_trade_no}");
                throw new \Exception("订单已支付,重复请求：{$out_trade_no}");
            }
            
            $model->pay_status = 1;
            $model->status = 10;
            $model->transaction_id = $data['transaction_id'] ?? $out_trade_no;
            $model->pay_time = time();
            $model->pay_type = 20;
            $result = $model->save();
            
            if (!$result) {
                \think\Log::record("订单更新失败：{$out_trade_no}");
                throw new \Exception("订单更新失败：{$out_trade_no}");
            }

            \app\common\model\AccountLog::create([
                    'user_id' => $model->user_id, 
                    'type'=> 2,
                    'money' => $model->price, 
                    'gift_money'=> 0,
                    'memo' =>  '',
                    'datatype'=>20,
                    'title' => '支出金额',
                ]);
            
            $orderGoodsModel = new \app\api\model\order\OrderGoods();
            $orderGoodsList = $orderGoodsModel::where(['order_master_id' => $model->id])->select();;
            
            foreach ($orderGoodsList as $orderGoods) {
                $order = new \app\api\model\order\Order();
                $result = $order->save([
                    'order_master_id'=>$model->id,
                    'order_goods_id'=>$orderGoods->id,
                    'user_id'=>$model->user_id,
                    'sole_id'=>$model->sole_id,
                    'hospital_id'=>$model->hospital_id,
                    'username'=>$model->username,
                    'userphone'=>$model->userphone,
                    'age'=>$model->age,
                    'gender'=>$model->gender,
                    'out_trade_no'=>$model->out_trade_no,
                    'transaction_id'=>$model->transaction_id,
                    'order_sn'=>createOrdersn($model->user_id,'S'),
                    'price'=>$orderGoods->real_price,
                    'original_price'=>$orderGoods->price,
                    'pay_type'=>$model->pay_type,
                    'order_type'=>10,
                    'pay_status'=>1,
                    'pay_time'=>time(),
                    'status'=>10,
                ]);

                if (!$result) {
                    \think\Log::record("子订单保存失败：{$out_trade_no}-{$orderGoods->id}");
                    throw new \Exception("子订单保存失败：{$out_trade_no}-{$orderGoods->id}");
                }else{
                    $orderGoods->order_id = $order->id;
                    $orderGoods->save();
                }
            }

            $resultPatient = \app\api\model\Patient::get([
                'doctor_id'=>$model->user_id,
                'hospital_id'=>$model->hospital_id,
                'username'=>$model->username,
                'age'=>$model->age,
                'gender'=>$model->gender,
            ]);
            if(!$resultPatient){
                $patient = new \app\api\model\Patient();
                $patient->doctor_id = $model->user_id;
                $patient->hospital_id = $model->hospital_id;
                $patient->username = $model->username;
                $patient->userphone = $model->userphone;
                $patient->age = $model->age;
                $patient->gender = $model->gender;
                $patient->save();
            }


        } catch (Exception $e) {
            \think\Log::record("回调逻辑处理错误:" . $e->getMessage(), "error");
            return json(['code' => 'FAIL', 'message' => '失败'], 500, ['Content-Type' => 'application/json']);
        }

        //下面这句必须要执行,且在此之前不能有任何输出
        if ( \addons\epay\library\Service::isVersionV3()) {
            return $pay->success()->getBody()->getContents();
        } else {
            return $pay->success()->send();
        }
        // return json(['code' => 'SUCCESS', 'message' => '成功']);
    }

    /**
     * 订单退款成功
     */
    public function notifyxOrderRefund()
    { 
        \think\Log::write('notifyx-refund:');
        $paytype = $this->request->param('paytype');
        $pay =  \addons\epay\library\Service::checkNotify($paytype);
        if (!$pay) {
            return json(['code' => 'FAIL', 'message' => '失败'], 500, ['Content-Type' => 'application/json']);
        }

        // // 获取回调数据，V3和V2的回调接收不同
        $data =  \addons\epay\library\Service::isVersionV3() ? $pay->callback() : $pay->verify();
        // $data = $this->request->param();
        try {
            //微信支付V3返回和V2不同
            if ( \addons\epay\library\Service::isVersionV3() && $paytype === 'wechat') {
                $data = $data['resource']['ciphertext'];
                $data['total_fee'] = $data['amount']['total'];
            }

            \think\Log::record($data);
            //获取支付金额、订单号
            $payamount = $paytype == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100;
            $out_refund_no = $data['out_refund_no'];
            \think\Log::record("回调成功，退款号：{$out_refund_no}，金额：{$payamount}");
            $model = new \app\api\model\order\Order();
            $list = $model::where(['out_refund_no' => $out_refund_no])->select();
            if (empty($list)) {
                throw new \Exception("退款订单不存在：{$out_refund_no}");
            }
            
            foreach ($list as $order) {
                $order->status = -20;
                $order->refund_id = $data['refund_id'];
                $order->tuikuantime = time();
                $result = $order->save();
                
                if (!$result) {
                    \think\Log::record("订单id：{$order->id},退款更新失败",'error');
                }
            }

            

            \app\common\model\AccountLog::create([
                    'user_id' => $model->user_id, 
                    'type'=> 1,
                    'money' => $payamount, 
                    'gift_money'=> 0,
                    'memo' =>  "取消订单{$out_refund_no},订单金额原路返回",
                    'datatype'=>30,
                    'title' => '微信订单退款',
                ]);

        } catch (Exception $e) {
            \think\Log::record("退款回调逻辑:" . $e->getMessage(), "error");
            return json(['code' => 'FAIL', 'message' => '失败'], 500, ['Content-Type' => 'application/json']);
        }

        //下面这句必须要执行,且在此之前不能有任何输出
        if ( \addons\epay\library\Service::isVersionV3()) {
            return $pay->success()->getBody()->getContents();
        } else {
            return $pay->success()->send();
        }
        // return json(['code' => 'SUCCESS', 'message' => '成功']);
    }


    /**
     * 转账成功
     */
    public function notifyxOrderTransfer()
    { 
        \think\Log::write('notifyx-transfer:');
        $paytype = $this->request->param('paytype');
        $pay =  \addons\epay\library\Service::checkNotify($paytype);
        if (!$pay) {
            return json(['code' => 'FAIL', 'message' => '失败'], 500, ['Content-Type' => 'application/json']);
        }

        // // 获取回调数据，V3和V2的回调接收不同
        $data =  \addons\epay\library\Service::isVersionV3() ? $pay->callback() : $pay->verify();
        // $data = $this->request->param();
        Db::startTrans();
        try {
            //微信支付V3返回和V2不同
            if ( \addons\epay\library\Service::isVersionV3() && $paytype === 'wechat') {
                $data = $data['resource']['ciphertext'];
                $data['total_fee'] = $data['transfer_amount'];
            }

            \think\Log::record($data);
            //获取支付金额、订单号
            $payamount = $data['total_fee'] / 100;
            $out_bill_no = $data['out_bill_no'];
            \think\Log::record("回调成功，转账号：{$out_bill_no}，金额：{$payamount}");
            $model = new \app\api\model\WithdrawOrder();
            $withdraw = $model::where(['out_bill_no' => $out_bill_no])->find();
            if (empty($withdraw)) {
                throw new \Exception("转账订单不存在：{$out_bill_no}");
            }
            $status = 0;
            
            if($data['state'] == 'SUCCESS'){
                $status = 20;
            }else if($data['state'] == 'FAIL'){
                $status = -20;
            }else if($data['state'] == 'CANCELING' || $data['state'] == 'CANCELLED'){
                $status = -10;
            }else{
                $status = 10;
            }
            $withdraw->status = $status;
            $withdraw->state = $data['state'];
            $withdraw->transfer_bill_no = $data['transfer_bill_no'];
            $withdraw->remark = isset($data['fail_reason']) ? $data['fail_reason'] : '';
            $result = $withdraw->save();
            
            if (!$result) {
                \think\Log::record("转账：{$out_bill_no},转账状态更新失败",'error');
                throw new \Exception("转账：{$out_bill_no},转账状态更新失败");
            }

            if($status == 20){
                $user = \app\api\model\User::where('id','=',$withdraw->user_id)->find();
                $user->setUpdateMoneyParams([
                    'memo'=>'提现申请成功',
                    'title'=>'提现申请成功',
                    'datatype'=>20
                ]);
                $res = $user->setDec('money',$withdraw->money);
                if(!$res){
                    \think\Log::record("提现申请失败：{$out_bill_no},用户余额更新失败",'error');
                    throw new \Exception("提现申请失败：{$out_bill_no},用户余额更新失败");
                }


                \app\common\model\AccountLog::create([
                        'user_id' => $withdraw->user_id, 
                        'type'=> 1,
                        'money' => $payamount, 
                        'gift_money'=> 0,
                        'memo' =>  "提现申请成功",
                        'datatype'=>30,
                        'title' => '申请提现',
                    ]);
            }

        } catch (Exception $e) {
            Db::rollback();
            \think\Log::record("退款回调逻辑:" . $e->getMessage(), "error");
            return json(['code' => 'FAIL', 'message' => '失败'], 500, ['Content-Type' => 'application/json']);
        }
        Db::commit();
        //下面这句必须要执行,且在此之前不能有任何输出
        if ( \addons\epay\library\Service::isVersionV3()) {
            return $pay->success()->getBody()->getContents();
        } else {
            return $pay->success()->send();
        }
        // return json(['code' => 'SUCCESS', 'message' => '成功']);
    }


    /**
     * 订单报告
     */
    public function notifyxOrderReport()
    { 
        \think\Log::write('notifyx-report:');
        $data = $this->request->param();
        \think\Log::record($data);

        return json(['code' => 'SUCCESS', 'message' => '成功']);
    }

}